<?php
require_once(dirname(__FILE__).'/adodb/adodb.inc.php');

/*
 Title: API Database
 class: db
    Class interact with database 
	
 package: Database

 notes:
	 Based in the OpenSource project e-groupware
	
* You need to include the classroom adodb.inc.php of the project * 

 ChangeLog:

 <Topic>1.4.2</Topic>
	- Bugfix - > Error with select using mysql corrected

 <Topic>1.4.5 - 25/Jun/2005</Topic>
	- Added It has supported the Transactions… It sees: <StarTrans> - <Commit> - <FailTrans> 

 <Topic>1.4.6 - 29/Jun/2005</Topic>
    - Adicionado Suporte para valores NULOS na inserção. Em implode_data();

 <Topic>1.4.8 - 22/08/2005</Topic>
	- BugFix - > Error when treating NULL values in implode_data (), added identical comparison (===) 
 <Topic>1.4.9 - 20/09/2005</Topic>	
	- Specialized Debug - > Permite to qualify or to incapacitate bDebug for the function 

<Topic>1.4.9.1 - 20/10/2005</Topic>	
	- Specialized Debug - > Permite to qualify or to incapacitate bDebug for the function 
	
<Topic>1.4.9.2 - 05/01/2006</Topic>

- BugFix - > Corrected bug in bDebug of the system when link had not been carried through ($this->oDBLink) 
- Modification: Persitência defined for setPersistent ($mValue); 
- Modification: Alteration of function use db_connect (), to define a configuration archive used constants not more and $GLOBALS - New Method: it prepares ($sSQL, $iLine, $sFile) - It prepares a SQL for execution 
- New Method: ExecutePrepare (Array (“test�?), $iLine, $sFile) - a prepared SQL Executes 
- Added to support for values NOW () in the insertion/update. In implode_data () 
      
<Topic>1.4.9.3 - 23/01/2006</Topic>
     - Added to method previous_record to come back a register.
      
 see also:

    <http://adodb.sourceforg.net>
*/
class db
{
/*	
vars: access private to integer: 
	$aRecord - mixed keeps the current aRecord 
	$bDebug - TRUE, qualifies the message of bDebug 
			  FALSIFIES, incapacitates the message of bDebug. boolean: 
	vars: access protected 
	vars: access public 
*/
private $oQuery = 0;
private $sPlan = '';
private $iLinkID = 0;
private $aRecord = Array();
private $oDBLink;
private $bDebug = TRUE;
private $bPersistent = FALSE;
public  $sEmailAdmin = '';

/*	
function: __Construct 
	Instance the class
	
parameters: 
	boolean: $bConnect - the classroom Allows to initiate a connection to the instance
  
*/
    function __construct( $bConnect = TRUE ){
        if ( $bConnect )
            $this->db_connect();
    }

    function setPersistent( $mValue ) { $this->bPersistent = $mValue; }

    /*
	function: db_connect 
		It connects the Database (Connect you database) 
	parameters: 
		string: 
			$host - Name of host (Accountin the host used will be connection) 
			$database - Name of the database (Accountin the name of database will be connection) to 
			$user - Name of usuÃ ¡ river (Accountin to user will be connection with $database) 
			$password - Password of the user (Accountin the password used will be connection) 
			$port - used Door for connection (used will be connection with host) 
			$type - Type of the database (Accountin the type of database will be create the connection will be this type) 
	Notes: 
		You need to have an archive of configuration for the pages to load the data automatically. 
		If to desire can pass directly to the function: 		
        define('CONNTYPE', 'postgresql8' );
        define('CONNHOST', 'localhost' );
        define('CONNDATABASE', 'localhost' );
        define('CONNUSER', 'postgres' );
        define('CONNPASS', '' );
        define('CONNPORT', '3306' );
        define('CONNPERSISTENT', TRUE );
    */
    function db_connect($host = NULL, $database = NULL, $user = NULL, $password = NULL, $port = NULL, $type = NULL)
    {
    $dbLink = '';

        /* If some parameter is null load the parameter of header*/
		
        if ( defined( CONNPERSISTENT ) )
        {
            $this->bPersistent = CONNPERSISTENT;
        }

        if (is_null($host))
        {
            $host = DB_HOST;
        }

        if (is_null($database))
        {
        $database = DB_NAME;
        }

        if (is_null($user))
        {
        $user = DB_USER;
        }

        if (is_null($password))
        {
        $password = DB_PASS;
        }
		
        if (is_null($port))
        {
        $port = DB_PORT;
        }

        if (is_null($type))
        {
            $type = DB_TYPE;
        }

        $this->clean_query();

        switch($type)
        {
            case "mysql":
            $this->oDBLink = NewADOConnection( $type );

                if ( $this->bPersistent )
                {
                $this->oDBLink->pconnect($host, $user, $password, $database) or die("Conexão com a base de dados ($database) Falhou! Causa: ".$this->oDBLink->ErrorMsg());
                
                }
                else
                {
                $this->oDBLink->connect($host, $user, $password, $database) or die("Conexão com a base de dados ($database) Falhou! Causa: ".$this->oDBLink->ErrorMsg());
                //echo __FILE__."[this is connect ".$password."]";
                }
            $this->iLinkID =& $this->oDBLink;
            //echo "MYSQL";
            break;
                    
            case "postgres7":
            $this->oDBLink = NewADOConnection( $type );
                if ( $this->bPersistent )
                {
                $this->oDBLink->pconnect($host, $user, $password, $database) or die("Conexão com a base de dados ($database) Falhou! Causa: ".$this->oDBLink->ErrorMsg());
                }
                else
                {
                $this->oDBLink->connect($host, $user, $password, $database) or die("Conexão com a base de dados ($database) Falhou! Causa: ".$this->oDBLink->ErrorMsg());
                }
            $this->iLinkID =& $this->oDBLink;
            break;

            case "postgres8":
            $this->oDBLink = NewADOConnection( $type );
                if ( $this->bPersistent )
                {
                $this->oDBLink->pconnect($host, $user, $password, $database) or die("Conexão com a base de dados ($database) Falhou! Causa: ".$this->oDBLink->ErrorMsg());
                }
                else
                {
                $this->oDBLink->connect($host, $user, $password, $database) or die("Conexão com a base de dados ($database) Falhou! Causa: ".$this->oDBLink->ErrorMsg());
                }
            $this->iLinkID =& $this->oDBLink;
            break;

            default:
                $this->Debug('Tipo de conexão não específicada', $sParam = '', __FILE__, __LINE__);
            break;
        }
    }
// Added by Quang on June, 2007
	function testConntection(){
		return $this->iLinkID;
	}
	/*
    	Returns a list of databases available on the server as an array. You have to connect to the server first. Only available for ODBC, MySQL and ADO.  
	*/
	function MetaDatabases(){
		return $this->oDBLink->MetaDatabases();
	}
	/*
    	Returns a list of tables available on the database as an array.  
	*/
	function MetaTables(){
		return $this->oDBLink->MetaTables('TABLES');
	}
	function MetaColumns($table){
		return $this->oDBLink->MetaColumns($table);
	}
	/*
	 Returns an array of column names for $table. 
	*/
	function MetaColumnNames($table){
		return $this->oDBLink->MetaColumnNames($table);
	}
    /*
//	
	function: setDebug 
		It qualifies the message of Debug, if incapacitated it returns bDebug 
	parameters: 
		boolean: 
			$bDebug - TRUE - qualifies, FALSIFIES - It incapacitates 	
    */
    function setDebug( $bDebug )
    {
        $this->Debug = $bDebug;
    }

    /*
	
	function: getErrorNo 
		returns the message from error 
	parameters: 
		boolean: 
			$bDebug - TRUE - qualifies, FALSIFIES - It incapacitates 	
    */
    function getErrorNo()
    {        	
		// Verifies the connection with the database 
        if (!is_object( $this->oDBLink ))
        {
            return NULL;
        }

        return $this->oDBLink->ErrorNo();
    }


    /*	
	function: db_disconnect 
	Connection closes the connection with the database - Close you the a database 	
    */
    function db_disconnect()
    {
        unset($iLinkID);
        unset($oQuery);
    }

    /*		
	function: StartTrans 
		It initiates a Transaction 
      see also:
         <Commit>
         <FailTrans>
    */
    public function StartTrans()
    {	
		// Verifies the connection with the database 	        
        if ( !is_object( $this->oDBLink ) )
        {
            $this->db_connect();
        }

        return $this->iLinkID->StartTrans();
    }

    /*
       function: FailTrans
	   	   It allows To inform an error of transaction, case is informed some the Commit will not be carried through 	   
      see also:
         <Comit>
         <StartTrans>
    */
    public function FailTrans()
    {
		// Verifies the connection with the database
        if (!is_object( $this->oDBLink ))
        {
            return false;
        }

        return $this->iLinkID->FailTrans();
    }

    /*
      function: Commit	
		In case of error in the transaction it gives to a RollBack senão makes a Commit 
      see also:
         <StartTrans>
         <FailTrans>
    */
    public function Commit()
    {
		// Verifies the connection with the database	        
        if (!is_object( $this->oDBLink ))
        {
            return false;
        }

        return $this->iLinkID->CompleteTrans();
    }


    /*
     function: bDebug
     Debug Function

     parameters:	 
	     string:	
			$message - the message for bDebug Accountins (Accountin the message will be bDebug) 
			$sParam - InformaÃ§ões extra (Accountin adds extra information) 
			$FILE - Name of the archive (Accountin the name of file) 
			$LINE - Line of the Archive (Accountin the line of file) 		 
    */
    private function Debug($message, $sParam = 'Sem parâmetros', $FILE = '', $LINE = '')
    {
        $sError = isset( $this->oDBLink ) ? $this->oDBLink->ErrorNo() : '';
        
        if ( $this->bDebug ) //@see header
        {
        $out = "
        <h2>!Debug!</h2><br />
        <font color=\"red\">$message</font><br />
        <strong>Acknowledgment </strong>: $sParam <br /><br />
        <strong>Archive :</strong> $FILE : <br /><strong>Line:</strong> $LINE <br />
        <strong>Error Number: </strong> ".$sError."
        ";

        die($out);
        }
        
        $sHeaders = "From: Quati <phuongtd@tuvinh.com>\r\n";        
        
        // Envia um e-mail para o administrador
        // No archive de configuração deve ser definida uma constante EMAILADMIN
        mail( $this->sEmailAdmin, "Debug Quati ".date( 'd/m/Y'), "An error in the class of data base occurred .\n$sParam\n\nError: $sError\n\nArchive : $FILE\nLine: $LINE\n", $sHeaders);
    }


    /*
      function: prepare
        prepare a SQL for execution

      parameters:

        string:	
		  $sSQL - SQL that will be prepared 
		  $iLine - Line of the archive that sent the SQL (Line where SQL is - USES __LINE__) 
		  $sFile - > Name of the archive that sent the SQL (Name of file where SQL is - USES __FILE__) 
		  $aParamValues - Array of the values 
    */
    function prepare( $sSQL, $iLine = NULL, $sFile = NULL )
    {
        $this->sPlan = $this->oDBLink->Prepare( $sSQL ) or $this->Debug('Error while executing: ',htmlentities($this->oDBLink->ErrorMsg())."<p>$sSQL</p>",$sFile, $iLine);
    }

    /*
      function: ExecutePrepare
        Execute a Prepared SQL to be executed

      parameters:
        string:	
		  $iLine - Line of the archive that sent the SQL (Line where SQL is - USES __LINE__) 
		  $sFile - > Name of the archive that sent the SQL (Name of file where SQL is - USES __FILE__) 
		  $aParamValues - Array of the values 		
      return: 	
		 true - Executed successfully
         false - Error in the execution 
    */
    function ExecutePrepare( $aParamValues,$iLine = NULL, $sFile = NULL )
    {
        if ( empty( $this->sPlan ) )  // Check if SQL is not empty
        {
            return false;
        }
		// Verifies the connection with the database        
        if ( !isset ( $this->oDBLink ) )
        {
            $this->db_connect();
        }

       $this->oQuery = $this->oDBLink->Execute( $this->sPlan, $aParamValues)
                           OR
                           $this->Debug('Error while executing: ',htmlentities($this->oDBLink->ErrorMsg())."<p>".$this->sPlan."</p>",$sFile, $iLine);

       return $this->oQuery;
    }

    /*
      function: execute_query
		Query SQL executes  - $sSQL Executes 
		
      parameters:
        string:	
		  $sSQL - SQL that will be executed (Accountin the sql that will be executed) 
		  $iLine - Line of the archive that sent the SQL (Line where SQL is - USES __LINE__) 
		  $sFile - > Name of the archive that sent the SQL (Name of file where SQL is - USES __FILE__) 		
      return:
		 true - Executed successfully
         false - Error in the execution 
    */
    function execute_query( $sSQL, $iLine = '', $sFile = '')
    {

        if ( empty($sSQL) )  // Check if SQL is not empty
        {
            return false;
        }

        // Verifies the connection with the database
        if ( !isset ( $this->oDBLink ) )
        {
            $this->db_connect();
        }

        $this->oQuery = $this->oDBLink->Execute( $sSQL )
                           OR
                           $this->Debug('Error while executing: ',htmlentities($this->oDBLink->ErrorMsg())."<p>$sSQL</p>",$sFile, $iLine);

        return $this->oQuery;
    }
	/*
	function fetch_row
		Fetch Array In Dataset
	return:
		Object	
	*/
    function fetch_row()
    {
    	return $this->oQuery->FetchRow();
    }
    /*
       function: clean_query
       Clear the query current result
    */
    function clean_query()
    {
        unset($this->oQuery);
    }

    /*
      function: num_rows
	    Recover the number of rows of query
      returns:
        integer:
        Return int number of rows found
    */
    function num_rows()
    {
        if (!$this->oQuery)
        {
        return false;
        }

        return $this->oQuery->RecordCount();
    }

    /*
       function: get_last_insert_id
		   get the id of the last insertion

       string:
         $table - Accountin the name of table
         $field - ontain the name of field that is primary key

       notes:	
	   	  $table and $field will be used when the database support will be added, they will go recoup the real id using where oid = $id in one method select 	   
 		  Table and Field will be used when the database to support, they will go to recuprar id real using where oid = $id in a method select  		  

       returns:
         integer:
			 Returns the ID from the last insertion
    */
    function get_last_insert_id($sTable = false,$sField = false)
    {
        if ( !is_object( $this->iLinkID ) )
        {
        return false;
        }

        /*	
		To catch the last inserted ID it can be used currval SELECT (id_sequence) - Postgresql 
        */
        return $this->iLinkID->Insert_ID($sTable,$sField);
    }
    
     
    /*
       function: get_affected_rows 	
	   It catches the affected line number (Get to number of affected rows) 	   

       Returns:
         integer:
         Retorna o número de Lines afetadas
    */
    function get_affected_rows()
    {
        if ( !is_object( $this->iLinkID ) )
        {
        return false;
        }

        return $this->iLinkID->Affected_Rows();
    }

    /*
      function: next_record	
		It moves for the next register to the solicitation ($aRecord Moves will be next of query) 
      Returns:	
		Boolean returns a value falsifies if the end of the result will be alcancado (Return bolean return falsifies if end of result will be reached) 
    */
    function next_record()
    {

        if (!$this->oQuery)
        {
        return False;
        }

        /*
        The variable $row is responsible for indicating when is necessary move to next record,
        in the first call of subclass next_record is not necessary move to next record and this is indicating
        when the variable $row is 0. If variable $row is 0 then subclass next_record is not executed and
        $row = $row + 1 ($row++). In the next call the $row is greater that 0 then the subclass next_record is executed}
        */
        static $row = 0;

        if ($row > 0)
        {
        $this->oQuery->MoveNext();
        }

        if ($this->oQuery->EOF)
        {
            $row =0;
            return false;
        }

        $row ++;
        return true;
    }
    
    /*
      function: previous_record
		Move for the previous registed
    */
    function previous_record()
    {

        if (!$this->oQuery)
        {
            return false;
        }

        $this->oQuery->MoveLast();
    }
    
    


    /*
      Function: field
	  	Returns the value from the current field

      Parameters:
        string:
	        $name - Name of the Field
    	    $stripslashes - applies function stripslashes before returning the field

      Returns:
        string:
        Returns the content from the current field
    */
    function field($name, $striplashes=true)
    {
        if ( !is_object( $this->oQuery ) )
            return null;
        
        if ($striplashes)
        {
            return stripslashes( $this->oQuery->fields($name) );
        }

        return $this->oQuery->fields($name);
    }


    /*
      Function: select
		 recoups values of the columns of the table

      Parameters:
        string:
	        $table Accountin the name of table
        	$sParam_end Accountin the parameters of the end of query
        	$iLine -> Line where SQL is - USE __LINE__
	        $sFile -> Name of file where SQL is - USE __FILE__
        array:
        	$where Accountin colunm name and value of comparison for where

        mixed:
            $cols
            	array - Accountin colunm name and value of colunm name
		        string - permitt pass directly the cols necessary
        boolean:
        	$like define if will be used the implode_data() for LIKE, if true the out is: colunm name LIKE '%value%'

      Returns:
			Return bolean return false if end of result will be reached

      see also:
        <execute_query>
    */
    function select($table, $cols, $where = FALSE, $sParam_end = FALSE, $like = FALSE, $iLine = '', $sFile = '')
    {
        if ($like)
        {
        $where = $this->implode_data(' AND ', $where,'LIKE');
        }
        else
        {
        $where = $this->implode_data(' AND ', $where);
        }

        // if it will be an Array of columns mounts
        if (is_array($cols))
        {
        $cols = $this->implode_data(',',$cols, 'NONE');
        }

        $sSQL = "SELECT $cols FROM $table WHERE ".(!empty($where) ? "$where" : '1=1 ').(!empty($sParam_end) ? " $sParam_end " : '');

        return $this->execute_query($sSQL, $iLine, $sFile);
    }

    /*
   Function: insert
	   inserts a line in the table
   Parameters:
       string:
           $table - Accountin the name of table
           $iLine - Line where SQL is - USE __LINE__
           $sFile - Name of file where SQL is - USE __FILE__
       array:
         $data Accountin colunm name and value of colunm name
         $where Accountin colunm name and value of comparison for where
		 
      see also:
      <update>
      <delete>
    */
    function insert($table, $data, $where = FALSE, $iLine = '', $sFile = '')
    {
        if (is_array($where))
        {
        $this->select($table,"*",$where, FALSE, FALSE, $iLine, $sFile);

            if ($this->num_rows() > 0)
            {
                return $this->update($table, $data, $where, $iLine, $sFile);
            }
        }

       $sSQL = "INSERT INTO $table ".$this->implode_data(',', $data, 'VALUES');
	
        return $this->execute_query($sSQL, $iLine, $sFile);
    }

    /*
       Function: update
           Update one or many rows in table in accordance with where

       Parameters:
	       string:
    	       $table - Accountin the name of table
               $iLine - Line where SQL is - USE __LINE__
               $sFile - Name of file where SQL is - USE __FILE__			   
      	   array:
         	   $data Accountin colunm name and value of colunm name
               $where Accountin colunm name and value of comparison for where
			   
        see also:
        <insert>
        <delete>
    */
    function update($table, $data, $where, $iLine = '', $sFile = '')
    {    	
        if (is_array($where))
        {
         $sSQL = "UPDATE $table SET ".$this->implode_data(', ', $data, 'UPDATE')." WHERE ".$this->implode_data(' AND ', $where);
		//echo $sSQL; die();
        return $this->execute_query($sSQL, $iLine, $sFile);
        }
    }
    
	function loadmenu(){
		$sSql = "SELECT * FROM module WHERE 1=1";
		$this->execute_query($sSql, __LINE__, __FILE__);
	}
    /*
       Function: delete
       	   Delete lines in accordance with where clause

       Parameters:
	       string:
    	     $table Accountin the name of table
        	 $iLine - Line where SQL is - USE __LINE__
	         $sFile - Name of file where SQL is - USE __FILE__
	         $limit - limits the number of exclusions (Postgresql does not support)
	       array:
    	     $data Accountin colunm name and value of colunm name
        	 $where Accountin colunm name and value of comparison for where

       see also:
        	 <insert>
		     <update>
    */
    function delete($table,$where,$limit = false, $iLine = '', $sFile = '')
    {
        $limit = is_numeric($limit) ? trim($limit) : false;
        $sSQL = "DELETE FROM $table WHERE ".$this->implode_data(' AND ',$where).(is_numeric($limit) ? " LIMIT '$limit' " : '');

        return $this->execute_query($sSQL, $iLine, $sFile);
    }

    /*
       Function: fetchField
       	   Get the dates of field, e.g: name of field, max length
		   
       Parameters:
          integer:
             $column - number of column
          boolean:
             $useMetaType - define the use of metatype

       see also:
			For the list of translation of metaType
	       <http://phplens.com/adodb/reference.functions.metatype.html>

       notes:

      - 0 name of column
      - 1 type of date (integer, varchar)
      - 2 max_length -> -1 not can be determine
	  
       returns:
       array $fld
    */
    function fetchField($column, $useMetaType = TRUE)
    {
        if (!$this->oQuery)
        {
        return False;
        }

        $fldObj = $this->oQuery->FetchField($column);

    $fld[] = $fldObj->name;
    $fld[] = $useMetaType ? $this->oQuery->MetaType($fldObj->type) : $fldObj->type;
    $fld[] = $fldObj->max_length;

    return $fld;
    }

    /*
      Function implode_data
      	  Implode data of array for use in SQL

      Parameters:
	      string:
    		  $glue - Accountin the glue that values will go to join the being the separator
		      $separator - Accountin the value that it will go to define the type of exit of the values
		  array:
		      $data - Accountin colunm name (keys[]) and value of colunm name ($values[])
      Returns:
    	  return the keys and values in accordance with type of $separator

      - $separator is "VALUES" then format of values will be an Array of this form: array('value1','value2') and out will be (KEYS) VALUES (VALUES separate by $glue)
      - $separator is "NONE" then format of values will be an Array of this form: array('value1','value2') and out will be only: VALUES separate by $glue
      - $separator is empty then format of values will be an Array of this form: array('key = value1','key = value2') and out will be only: VALUES separate by $glue
    */
    function implode_data($glue, $data, $separator = '')
    {

        if (is_array($data))
        {
            foreach($data as $key => $value)
            {
            $keys[] = $key;

                switch ($separator)
                {
                    case 'VALUES':
                        // Add support to NULL VALUES
                        if ($value=="NULL" || is_null( $value ) )
                            $values[] = "NULL";
                        else if ( $value == 'NOW()')
                            $values[] = "NOW()";
                        else
                            $values[] = "'".trim(addslashes($value))."'";

                    break;

                    case 'NONE':
                    $values[] = ''.htmlentities(trim(addslashes($value))).'';
                    break;

                    case 'LIKE':
                    $values[] = trim($key).' LIKE \'%'.trim(addslashes($value)).'%\'';
                    break;
                        
                    case 'UPDATE':
                        // Add support to NULL VALUES
                        if ( $value=="NULL" || is_null( $value ) )
                            $values[] = trim($key)." = NULL";
                        else
                            $values[] = trim($key)." = '".trim(addslashes($value))."'";
                    break;

                    default:

                        // Add support to NULL VALUES
                        if ( $value=="NULL" || is_null( $value ) )
                            $values[] = trim($key)." IS NULL";
                        else
                            $values[] = trim($key)." = '".trim(addslashes($value))."'";

                    break;
                }
            }

        return ($separator==='VALUES' ? '('.implode(',',$keys).') VALUES (' : '').implode($glue,$values).($separator==='VALUES' ? ')' : '');
        }
        else
        {
        return trim(addslashes($data));
        }
    }
}

/*
section: Example

topic: Include this class for use
include()
include_once("class.dbcontrol.inc.php");

topic: Include a classe
new

$db = new db;

topic:  Insert
insert()

$db->insert("tb_conteudo_categoria",array("Name"=>"ABC"),array("Name"=>"ABC"));

topic: Last id inserted
get_last_insert_id()

echo "Last ID: ".$db->get_last_insert_id()."<br><br>";

topic: Delete
delete()

$db->delete('tb_conteudo_categoria',array("cod"=>$db->get_last_insert_id()));

topic: Number of affected rows
get_affected_rows()

echo "Line affected: ".$db->get_affected_rows()."<br><br>";

topic: Select
select()

$select = $db->select('tb_conteudo_categoria', array("cod", "Name", "descricao"),array("Name" => "a"), "ORDER BY cod", true);

topic: Number of line after selected
num_rows()

$numrows = $db->num_rows();

topic: Covering all the registers found in one select
next_$aRecord()

while ($db->next_$aRecord())
{

    $accounts[] = array(

                'cod'  => $db->field('cod'),

                'Name'  => $db->field('Name')

    );

}


if (is_array($accounts)){

    foreach($accounts as $key => $data)

    {

        echo "cod -> ".$accounts[$key]["cod"]." ------ Name: ".$accounts[$key]["Name"]."<br><br>";

    }

}

echo  "<br>Total de Rows: $numrows";

topic: Disconect
db_disconnect();

$db->db_disconect();
*/
?>
